package com.ztstkj.lzscale

import android.icu.text.SimpleDateFormat
import com.blankj.utilcode.util.TimeUtils
import com.google.common.hash.HashCode
import com.google.gson.Gson
import com.ztstkj.lzservices.extension.ByteArrayExtension.crc16
import com.ztstkj.lzservices.extension.ByteArrayExtension.crc16Verify
import com.ztstkj.lzservices.extension.ByteArrayExtension.dump
import com.ztstkj.lzservices.extension.ByteArrayExtension.getCrc16String
import com.ztstkj.lzservices.extension.ByteArrayExtension.lowToHigh
import com.ztstkj.lzservices.extension.ByteArrayExtension.to2SignInt
import com.ztstkj.lzservices.extension.ByteArrayExtension.toHexStr
import com.ztstkj.lzservices.extension.ByteArrayExtension.toInt
import com.ztstkj.lzservices.extension.ExceptionExt.toStackTraceString
import com.ztstkj.lzservices.extension.IntExtension.dump
import com.ztstkj.lzservices.extension.IntExtension.toChinese
import com.ztstkj.lzservices.extension.IntExtension.toHex1X
import com.ztstkj.lzservices.extension.IntExtension.toHex2X
import com.ztstkj.lzservices.extension.IntExtension.toHex4X
import com.ztstkj.lzservices.extension.LongExtension.toHex4X
import com.ztstkj.lzservices.extension.StringExtension.dump
import com.ztstkj.lzservices.extension.StringExtension.str2ByteArray
import com.ztstkj.lzservices.serialports.ModbusData
import com.ztstkj.lzservices.serialports.ModbusError
import com.ztstkj.lzservices.utils.HexUtil
import org.junit.Assert
import org.junit.Test
import java.math.BigDecimal
import java.math.RoundingMode
import java.time.LocalDateTime
import java.util.Calendar
import java.util.Locale

/**
 * Example local unit test, which will execute on the development machine (host).
 *
 * See [testing documentation](http://d.android.com/tools/testing).
 */
class HexUtilUnitTest {
    @Test
    fun toHexStr_isCorrect() {
        //01 03 00 00 00 0A C5 CD
        //01     从设备地址：1字节
        //03     功能码：1字节
        //00 00  起始寄存器地址：2字节
        //00 0A  寄存器数量：2字节
        //C5 CD  CRC校验：2字节
        val byteArray = byteArrayOf(1, 3, 0, 0, 0, 10, -59, -51)
        val hex = HexUtil.toHexStr(byteArray, " ")
        System.err.println(hex)
        Assert.assertEquals("01 03 00 00 00 0A C5 CD", hex)
    }

    @Test
    fun intArrayCrc16_isCorrect() {
        val intArray = byteArrayOf(1, 3, 0, 0, 0, 10)
        val byteArray = intArray.crc16()
        for (byte in byteArray) {
            System.err.println("byte:${byte}")
        }

        Assert.assertEquals(4, 2 + 2)
    }

    @Test
    fun hexUtiltoHexStr() {
        val byteArray = byteArrayOf(-59, -51)
        val result = HexUtil.toHexStr(byteArray)
        System.err.println("hexUtiltoHexStr:$result")
        Assert.assertEquals("C5CD", result)
    }

    @Test
    fun toHexString() {
        val byteArray = byteArrayOf(-59, -51)
        val result = byteArray.toHexStr(" ")
        System.err.println("扩展函数toHexString:$result")
        Assert.assertEquals("C5 CD", result)
    }

    @Test
    fun hashCodeFromBytes() {
        val byteArray = byteArrayOf(-59, -51)
        val crcString = HashCode.fromBytes(byteArray).toString()
        System.err.println("HashCode.fromBytes:$crcString")
        Assert.assertEquals("c5cd", crcString)
    }

    @Test
    fun crc16Verify_isCorrect() {
        val byteArray = byteArrayOf(1, 3, 0, 0, 0, 10, -59, -51)
        val result = byteArray.crc16Verify()
        System.err.println("结果：$result")
        Assert.assertEquals(true, result)
    }

    @Test
    fun getCrc16String_isCorrect() {
        val byteArray = byteArrayOf(1, 3, 0, 0, 0, 10)
        val result = byteArray.getCrc16String(false)
        System.err.println("结果1：${result[0]}")
        System.err.println("结果2：${result[1]}")
        val crcString = HashCode.fromBytes(result)
        System.err.println("校验码：$crcString")
        Assert.assertEquals(
            "C5CD".lowercase(), crcString.toString()
        )
    }

    @Test
    fun intToByte_isCorrect1() {
        val year = 2025
        System.err.println("年：${year.toByte()}")
        Assert.assertEquals(1, 1)
    }

    @Test
    fun intToByteArray_isCorrect() {
        val year = 2025
        val byteArray = ByteArray(2)
        val lowH = ((year shr 8) and 0xff).toByte()
        val lowL = (year and 0xff).toByte()
        byteArray[0] = lowH
        byteArray[1] = lowL
        System.err.println("年：${lowH},${lowL}")
        Assert.assertEquals(1, 1)
    }

    @Test
    fun intToByteArray2_isCorrect() {
        val number = 2025
        //val bytes = number.toByteArray() // 将Int转换为ByteArray，这将根据平台返回4个或8个字节（取决于Int的大小）
        // 如果你需要确切的两个字节，你可以手动拆分，例如：
        val byte1 = (number shr 8).toByte() // 右移8位，然后转换为Byte
        val byte2 = number.toByte() // 直接转换为Byte

        System.err.println("Byte 1: ${byte1.toInt()}") // 输出第一个字节的值
        System.err.println("Byte 2: ${byte2.toInt()}") // 输出第二个字节的值
        Assert.assertEquals(1, 1)
    }

    @Test
    fun byteToInt_isCorrect() {
        val byteA: Byte = -23
        System.err.println("年：${byteA.toInt()}")
        Assert.assertEquals(1, 1)
    }

    @Test
    fun bytesToInt_isCorrect() {
        var byteArray = byteArrayOf(-23, 7)
        System.err.println("年：${byteArray.to2SignInt()}")

        byteArray = byteArrayOf(7, -23)
        System.err.println("年：${byteArray.to2SignInt()}")
        Assert.assertEquals(1, 1)
    }

    @Test
    fun intToHex() {
        2025.toHex4X().dump("年")
        1.toHex2X().dump("从站地址")
        16.toHex2X().dump("功能码")
        6.toHex4X().dump("起始位置")
        11.toHex4X().dump("寄存器数量")
        22.toHex2X().dump("字节数量")
        2025.toHex4X().toByteArray().dump()
    }

    @Test
    fun hexToByteArray() {
        "00 0A".toByteArray().dump()
    }

    @Test
    fun hexToInt() {
        "00 00 60 0D".toByteArray().toInt().dump()
    }

    @Test
    fun byteArrayToInt() {
        val b = byteArrayOf(0, 10)
        b.toInt().dump()
    }

    @Test
    fun byteArrayToHex() {
        val b = byteArrayOf(0, 10)
        val c = b.toHexStr("")
        Integer.parseInt(c, 16).dump()
    }

    @Test
    fun modbusData_card_isCorrect() {
        val hexString = "01 10 00 0A 00 02 04 91 CD 00 69 0E FD"
        //val hexString = "01 10 00 0A 00 02 04 60 0D 00 00 FC 13"
        //var hexString="01 10 00 0A 00 02 04 60 0D 00 00 9A 15"
        val byteArray = hexString.toByteArray()
        byteArray.forEachIndexed { index, item -> System.err.println("array[${index}]=$item;") }
        //byteArray.dump()
        val modbusD = ModbusData(byteArray)
        Gson().toJson(modbusD).dump()
    }
    @Test
    fun modbusData_card_isCorrect2() {
        val hexString = "01 10 00 0A 00 02 04 6B 9D E5 5C B4 B3"
        //var hexString="01 10 00 0A 00 02 04 60 0D 00 00 9A 15"
        val byteArray = hexString.toByteArray()
        //byteArray.dump()
        val modbusD = ModbusData(byteArray)
        Gson().toJson(modbusD).dump()
    }

    @Test
    fun modbusData_weight_isCorrect() {
        val hexString =
            "01 10 00 06 00 0B 16 00 00 00 00 00 00 00 00 00 00 00 00 42 F0 00 00 00 00 00 00 00 00 D1 36"
        //var hexString="01 10 00 06 00 0B 16 07 E9 05 15 0F 0F 0F 03 60 0D 00 00 01 45 00 00 00 01 00 01 00 01 6A CD"
        //var hexString="01 10 00 0A 00 02 04 60 0D 00 00 9A 15"
        val byteArray = hexString.toByteArray()
        //byteArray.dump()
        val modbusD = ModbusData(byteArray)
        Gson().toJson(modbusD).dump()
        modbusD.success().toHexStr(" ").dump()
    }

    @Test
    fun enumOrdinal() {
        val enuma = ModbusError.NOT_FOUND_CARD
        enuma.num.dump()
        enuma.ordinal.dump()
    }

    @Test
    fun create_only_weight1() {
        var weight = 4987.toHex4X().str2ByteArray()
        weight.dump()
    }
    @Test
    fun create_only_weight() {
        var weight = 3907.toHex4X().str2ByteArray().lowToHigh().toHexStr(" ")
        "01 10 00 0C 00 02 04 $weight".dump() //01 10 00 0C 00 02 04 0F 43 00 00
        weight = 1205.toHex4X().str2ByteArray().lowToHigh().toHexStr(" ")
        "01 10 00 0C 00 02 04 $weight".dump() //01 10 00 0C 00 02 04 04 B5 00 00
        weight = 5.toHex4X().str2ByteArray().lowToHigh().toHexStr(" ")
        "01 10 00 0C 00 02 04 $weight".dump()//01 10 00 0C 00 02 04 00 05 00 00
        weight = 6.toHex4X().str2ByteArray().lowToHigh().toHexStr(" ")
        "01 10 00 0C 00 02 04 $weight".dump()//01 10 00 0C 00 02 04 00 06 00 00
        weight = 0.toHex4X().str2ByteArray().lowToHigh().toHexStr(" ")
        "01 10 00 0C 00 02 04 $weight".dump()//01 10 00 0C 00 02 04 00 06 00 00
        "%.2f".format(1568.toDouble() /1000).dump()
    }

    @Test
    fun create_only_category() {
        var category = 1.toHex2X().str2ByteArray().toHexStr(" ")
        "01 10 00 10 00 01 02 $category".dump()//01 10 00 10 00 01 02 00 01
        category = 2.toHex2X().str2ByteArray().toHexStr(" ")
        "01 10 00 10 00 01 02 $category".dump()//01 10 00 10 00 01 02 00 02
        category = 3.toHex2X().str2ByteArray().toHexStr(" ")
        "01 10 00 10 00 01 02 $category".dump()//01 10 00 10 00 01 02 00 03
        category = 4.toHex2X().str2ByteArray().toHexStr(" ")
        "01 10 00 10 00 01 02 $category".dump()//01 10 00 10 00 01 02 00 04
        //1 为易腐垃圾； 2 为可回收物； 3 为有害垃圾； 4 为其他垃圾；


    }
    @Test
    fun create_card() {
        //12294998  二期公用卡4
        //12297142   1幢1单元101
        //6918605
        //3848039325
        val card:Int=12260516 //01 10 00 0A 00 02 04 14 A4 00 BB
        //val card = 6918605L     //01 10 00 0A 00 02 04 91 CD 00 69 0E FD
        //val card =6918605     //01 10 00 0A 00 02 04 91 CD 00 69
        //val card = 3848039325 // 01 10 00 0A 00 02 04 6B 9D E5 5C B4 B3
        card.toHex4X().dump()
        val orgin = card.toHex4X().str2ByteArray()
        orgin.toHexStr(" ").dump("正序")
        val cardReverse = orgin.lowToHigh().toHexStr(" ")
        "01 10 00 0A 00 02 04 $cardReverse".dump()//01 10 00 0A 00 02 04 91 CD 00 69
    }

    @Test
    fun create_weight() {
        val time = LocalDateTime.now()
        var year = time.year.toHex2X().str2ByteArray().toHexStr(" ")
        var month = time.monthValue.toHex1X().str2ByteArray().toHexStr(" ")
        var day = time.dayOfMonth.toHex1X().str2ByteArray().toHexStr(" ")
        var hour = time.hour.toHex1X().str2ByteArray().toHexStr(" ")
        var minute = time.minute.toHex1X().str2ByteArray().toHexStr(" ")
        var sec = time.second.toHex1X().str2ByteArray().toHexStr(" ")
        var week = time.dayOfWeek.value.toHex1X().str2ByteArray().toHexStr(" ")
        //12294998  二期公用卡4
        //
        var cardInt = 6918605 //
        var weightInt = 5647
        var card = cardInt.toHex4X().str2ByteArray().lowToHigh().toHexStr(" ")
        var weight = weightInt.toHex4X().str2ByteArray().lowToHigh().toHexStr(" ")
        var rate = 2.toHex2X().str2ByteArray().toHexStr(" ")
        var category1 = 1.toHex2X().str2ByteArray().toHexStr(" ")
        var category2 = 4.toHex2X().str2ByteArray().toHexStr(" ") //垃圾类别
        "01 10 00 06 00 0B 16 $year $month $day $hour $minute $sec $week $card $weight $rate $category1 $category2".dump()
        //01 10 00 06 00 0B 16 07 E9 06 19 09 2D 1A 03 91 CD 00 69 13 7B 00 00 00 02 00 01 00 04
    }
    @Test
    fun weight_tostring() {
        var weightInt = 115
        var weightDouble=weightInt.toDouble()
        weightDouble.toChinese().dump()
        var arry=arrayOf(1,2,3,4)
        var result=arry.take(10)
        result.forEach {  item-> item.dump() }
    }
    @Test
    fun int_tostring() {
        var r= BigDecimal(135).divide(BigDecimal(1000),2,RoundingMode.HALF_UP)
        println("结果：${r}")
        println("结果：${String.format("%.2f", r)}")

        var d=135/1000.0
        println("结果：${d}")
    }
    @Test
    fun calendar_test(){
        var calendar = Calendar.getInstance()
        var yearInt = calendar.get(Calendar.YEAR)
        var monthInt = calendar.get(Calendar.MONTH)+1
        var dayInt = calendar.get(Calendar.DAY_OF_MONTH)
        var hourInt = calendar.get(Calendar.HOUR_OF_DAY)
        var minuteInt = calendar.get(Calendar.MINUTE)
        var secondInt = calendar.get(Calendar.SECOND)
        var weekInt = calendar.get(Calendar.DAY_OF_WEEK)-1
        if(weekInt==0) weekInt=7
        yearInt.dump("年")
        monthInt.dump("月")
        dayInt.dump("日")
        hourInt.dump("小时")
        minuteInt.dump("分钟")
        secondInt.dump("秒")
        weekInt.dump("星期")
        var sdf =  SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
        println(sdf.format(calendar.getTime()))
    }
    @Test
    fun throwable_test(){
        try {
           "a".toInt()
        }catch (e: Throwable){
            println( e.toStackTraceString())
        }
    }
    @Test
    fun util_test(){
        TimeUtils.getNowString().dump()
        TimeUtils.getNowString()
        TimeUtils.getNowDate().time.dump()
        TimeUtils.getNowMills().dump()
        TimeUtils.getNowString()

    }
}